#ifndef     __CTRL_H
#define     __CTRL_H

#include <stdint.h>
#include "../utils/nocopyable.h"
#include "../rtos/mutex.h"
#include "../utils/error.h"

namespace driver {

class Ctrl : private utils::NoCopyable {

public:
    static constexpr uint32_t LED_DELAY_CLOSE = 30 * 1000;

    static constexpr uint32_t RUN_TIMEOUT = 10 * 1000;
    static constexpr uint32_t PICK_TIMEOUT = 4 * 1000;

    utils::Error cargo_is_valid(uint8_t row, uint8_t col) {
        if ((row < 1) || (row > 8) || (col < 1) || (col > 13)) {
            return utils::ec::INVALID;
        }
        return utils::ec::OK;
    }

    void init();

    /**
     * @param row >=1 <= 8
     * @param col >=1 <= 13
     */
    void select(uint8_t row, uint8_t col, bool val);

    utils::Error run_with_state(uint8_t row, uint8_t col, bool state);
    utils::Error run_with_state(uint8_t row, bool state);
    utils::Error run_pick(uint8_t row, uint8_t col);
    void close_all();

    void reset();

    void beep_on();
    void beep_off();

    void led_open();
    void led_close();

    void led_poll(uint32_t tick) {
        if (!m_led_close_flag) {
            return;
        }
        
        m_led_tick += tick;
        if (m_led_tick >= LED_DELAY_CLOSE) {
            m_led_tick = 0;
            led_close();
            m_led_close_flag = false;
        }
    }

    void recount_led_close() {
        m_led_tick = 0;
        m_led_close_flag = true;
    }

private:
    uint32_t m_led_tick = 0;
    bool m_led_close_flag = false;
};

extern Ctrl ctrl;

}


#endif
